package com.stars.easyms.monitor.impl;

import com.stars.easyms.monitor.handler.EasyMsRequestHandler;
import com.stars.easyms.monitor.MonitorFunc;
import com.stars.easyms.monitor.MonitorRequestHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>className: EasyMsMonitorRequestHandler</p>
 * <p>description: EasyMs监控请求处理类</p>
 *
 * @author guoguifang
 * @date 2019/11/20 11:38
 * @since 1.4.0
 */
@Slf4j
public final class EasyMsMonitorRequestHandler implements EasyMsRequestHandler {

    private static List<MonitorFunc> monitorFuncList;

    static {
        try {
            Set<MonitorFunc> localMonitorFuncSet = new HashSet<>();

            // 获取所有的实现了MonitorFun接口的类
            ServiceLoader<MonitorFunc> monitorFuncServiceLoader = ServiceLoader.load(MonitorFunc.class);
            for (MonitorFunc monitorFunc : monitorFuncServiceLoader) {
                localMonitorFuncSet.add(monitorFunc);
            }

            // 获取所有的实现了EasyMsMonitorRequestHandler接口的类
            ServiceLoader<MonitorRequestHandler> monitorRequestHandlerServiceLoader = ServiceLoader.load(MonitorRequestHandler.class);
            for (MonitorRequestHandler easyMsMonitorRequestHandler : monitorRequestHandlerServiceLoader) {
                localMonitorFuncSet.add(easyMsMonitorRequestHandler);
            }

            // 排序
            monitorFuncList = localMonitorFuncSet.stream()
                    .sorted(Comparator.comparingInt(MonitorFunc::getOrder))
                    .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));

            // 按照顺序打印扫描到的接口信息
            for (MonitorFunc monitorFunc : monitorFuncList) {
                log.info("Found {} monitor func: {}, order: {}!", monitorFunc.getModuleName(),
                        monitorFunc.getClass().getCanonicalName(), monitorFunc.getOrder());
            }
        } catch (Exception ex) {
            log.error("Initialization MonitorFunc failed!", ex);
        }
    }

    @GetMapping("monitor")
    public void toIndex(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        request.getRequestDispatcher("/webjars/easyms/monitor/monitor.html").forward(request, response);
    }

    @PostMapping("easy-ms/monitor/getInfo")
    @ResponseBody
    public Map<String, Object> getMonitorInfo() {
        Map<String, Object> monitorSummaryMap = new LinkedHashMap<>();
        for (MonitorFunc monitorFunc : monitorFuncList) {
            monitorSummaryMap.put(monitorFunc.getModuleName(), monitorFunc.getMonitorInfo());
        }
        return monitorSummaryMap;
    }
}
